//standard
#include <vector>
#include <string>
#include <iostream>


// components
#include <tree.h>
#include <stlhelper.h>
#define DEBUG_LEVEL 6
#include <debug_func.h>
#include <tree_ops.h>
#include <print_error.h>

#include "get_arg.h"

using std::vector;
using std::string;
using std::cout;
using std::cin;
using std::cerr;
using std::istream;
using namespace bcpp_tree_ops;
using namespace bcpp_tree;
using bcpp_tree_ops::op_tree_get_names;




//8888888888888888888888888888888888888888888888888888888888888888888888888888888888888888

//	main

//8888888888888888888888888888888888888888888888888888888888888888888888888888888888888888
int main (int argc, char *argv[])
{

	t_program_args args;

	try
	{

	debug_func_cerr(5);

	// we use cout to print progress so flush per call
	cout.setf(std::ios_base::unitbuf);

	std::ios::sync_with_stdio(false);

	if (!process_command_line_options(argc, argv, args))
		return 1;


//    char buff[4096];
//    cin.rdbuf()->pubsetbuf(buff, 32768); // enable buffering


	//
	//	read tree from cin
	//
	args.VERBOSE() << "\tReading tree...\n";
	bcpp_tree::t_tree tree;
	tree.set_sort_by_names(args.branches_alpha);
	if (args.branches_alpha)
		args.VERBOSE() << "\tSorting branches by alphabetical order...\n";

	unsigned line_cnt = 0;
	cin >> t_tree_io_wrapper(tree, line_cnt);
	//read_tree_from_stream(cin, tree, tree_name);


	args.VERBOSE() << "\tRetrieving names of leaves...\n";
	// calculate branch lengths
	vector<string> leaf_names;
	get_tree_names(tree, std::back_inserter(leaf_names));
	if (args.names_alpha)
	{
		args.VERBOSE() << "\tSorting leaf names by alphabetical order...\n";
		sort(leaf_names.begin(),  leaf_names.end());
	}
	std::copy(leaf_names.begin(), leaf_names.end(), std::ostream_iterator<string>(cout, "\n"));

	}
	catch (std::exception& e)
	{
		std_print_error(args.CERR(),  e.what());
		return 1;
	}

	return 0;
}



